<?php

namespace Application\Model;

use Zend\Db\Adapter\Adapter;
use Zend\Db\Sql\Sql;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;
use Zend\Db\Sql\Select;
use Zend\Db\Sql\Where;
use Zend\Session\Container; // We need this when using sessions

use Zend\Authentication\AuthenticationService;
use Application\Model\Role as Role;

use Application\Model\RegionsTable;
use Application\Model\PaysTable;
use Application\Model\AgenceTable;
use Application\Model\ActivitesSejourTable;
use Application\Model\thematiquesTable;

use Application\Service\StringService as StringService;

class RechercheTable extends SejourTable
{
    protected $table ='Sejour';
    protected $tableName ='Sejour';
    
    protected $tableGateway;
    protected $regionsTable;
    protected $paysTable;
    protected $agenceTable;
    protected $activitesSejourTable;    
    protected $thematiquesTable;    

    protected $_listeFiltresUtilProprietes = array( "paysUtil", "regionsUtil", "activitesUtil");


    public function __construct(TableGateway $tableGateway, 
                                RegionsTable $regionsTable, 
                                PaysTable $paysTable, 
                                ActivitesSejourTable $activitesSejourTable,
                                AgenceTable $agenceTable,
                                ThematiquesTable $thematiquesTable,
                                StringService $stringService)
    {
        $this->tableGateway = $tableGateway;
        $this->regionsTable = $regionsTable;
        $this->paysTable = $paysTable;
        $this->activitesSejourTable = $activitesSejourTable;
        $this->stringService = $stringService;
        $this->agenceTable = $agenceTable;
        $this->thematiquesTable = $thematiquesTable;
    }
    
    /* Frontoffice */
    /* Retourne les infos à afficher sur la page d accueil */
    public function resultatRecherche ($filtres)
    {
        $where = new Where();

        $where = $this->filtrerSejours ($filtres);

        $sql = new Sql($this->tableGateway->getAdapter());
        $select = $sql->select();

        $select->from($this->tableGateway->table)
            ->join('Pays', 'Sejour.paysId = Pays.idPays', array('libellePays'), 'left')
            ->join('Regions', 'Sejour.regionId = Regions.idRegions', array('libelleRegions'), 'left')
            ->join('Agence', 'Sejour.agenceId = Agence.id', array('agenceLibelle' => 'libelle', 'agenceImageURL' => 'imageUrl'))
            ->join('ActivitesSejour', 'Sejour.activiteId = ActivitesSejour.idAS', array('libelleAS'), 'left')
            ->join('TypesSejour', 'Sejour.typeSejoursId = TypesSejour.idTS', array('libelleTS'), 'left')
            // ->join('Sejour_date', 'Sejour.id = Sejour_date.sejourId', array('*'), 'left')
            ->where($where)
            ->group('Sejour.Id')
            ->order('titre ASC');
        
        $statement = $sql->prepareStatementForSqlObject($select);
        $resultSet = $statement->execute();

        return $this->toArray ($resultSet);
    }

    public function toArray ($resultSet)
    {
        $entities = array();
        
        foreach ($resultSet as $row) {
            $obj = new Recherche();
            $obj->exchangeArray( (array) $row);
            $entities[] = $obj;
        }
        
        return $entities;
    }

    public function filtrerSejours ($filtres)
    {
        $where = new Where();

        if(count($filtres) == 0 ) return $where;

        foreach ($filtres as $key => $values) {

            /* filtres par pays */
            if(array_key_exists('paysId', $values) && count($values['paysId']) > 0 ) {
                $where->in("Sejour.paysId", $values['paysId']);
            }

            /* filtres par région */
            if(array_key_exists('regionId', $values) && count($values['regionId']) > 0 ) {
                $where->in("Sejour.regionId", $values['regionId']);
            }

            /* filtres par activités */
            if(array_key_exists('activiteId', $values) && count($values['activiteId']) > 0 ) {
                $where->in("Sejour.activiteId", $values['activiteId']);
            }

            /* filtres par agence : exclu param dans url */
            if(array_key_exists('agenceId', $values) && count($values['agenceId']) > 0 ) {
                $where->in("Sejour.agenceId", $values['agenceId']);
            }
        }

        // // filtre date de départ : table sejour_date (liste des disponibilités)
        // if($filtres['dateDepart'] != "") {
            
        //     $sub = $this->tableGateway->getSql()->select();

        //     $sub->columns(array(new \Zend\Db\Sql\Expression('Sejour.id')))
        //         ->where(array('Sejour_date.dateDebut' => date($filtres['dateDepart']) ))
        //         ->group('Sejour.Id');

        //     $where->In('Sejour.Id', $sub );
        // }
        return $where;
    }

    public function initialiser_les_filtres_page_accueil () {
        /* Check la session pour recharger les valeurs */
            $user_session = new Container('filtresession');

            $filtreValues = $user_session->filtresCourant;
            $filtresAJour = $user_session->filtresAJour; // les filtres sur le côté à jour en session

            if( $filtresAJour != null && count($filtresAJour) > 0 ) {

                $filtresSelectionnesReconstruits = $this->reconstruire_filtres_selectionnes_recherche_accueil ( $filtreValues );

                $datasToView = array_merge($filtresAJour, array( "filtresSelection" => $filtresSelectionnesReconstruits, "filtresCourant" => $filtreValues ));

                return $datasToView;
            } else {

                return $this->filtresRechercheAccueil ();
            }
    }

    /* liste de choix : pays, régions, activités, thématiques */
    public function filtresRechercheAccueil () {
        $paysUtilises = $this->paysTable->fetchAllUsed();          

        $regionsUtilises = $this->regionsTable->fetchAllUsed();

        $activitesUtilises = $this->activitesSejourTable->fetchAllUsed();

        $thematiquesUtilises = $this->thematiquesTable->fetchAllUsed();

        return array("paysUtil" => $paysUtilises, "regionsUtil" => $regionsUtilises, "thematiquesUtil" => $thematiquesUtilises, "activitesUtil" => $activitesUtilises );
    }


    /* On recréer les filtres en fonction des filtres précédents */
    public function reCreationFiltres ( $resultSet , $filtreValues ) {
        $listePaysIds = array();
        $listeRegionsIds = array();
        $listeActivitesIds = array();

        $resulatsToView["resultSet"] = $resultSet;
        
        $isFiltrePaysPresent = $this->isFiltre ($filtreValues, 'paysId');
        $isFiltreRegionsPresent = $this->isFiltre ($filtreValues, 'regionId');
        $isFiltreActivitesPresent = $this->isFiltre ($filtreValues, 'activiteId');

        if( $isFiltrePaysPresent ) {
            $resulatsToView["paysUtil"] = null;
        }
        if( $isFiltreRegionsPresent ) {
            $resulatsToView["regionsUtil"] = null;
        }
        if( $isFiltreActivitesPresent ) {
            $resulatsToView["activitesUtil"] = null;
        }

        /* parcours de tous les séjours filtrés et retournés */
        foreach ($resultSet as $key => $value) {
            
            /* reconstruction du filtre PAYS */
            if( !$isFiltrePaysPresent ) {
                if( isset($value->paysId) && !in_array($value->paysId, $listePaysIds) ) {
                    array_push($listePaysIds, $value->paysId);
                } else {
                    unset($resulatsToView["paysUtil"]);
                }
            } 

            /* reconstruction du filtre Regions */            
            if( !$isFiltreRegionsPresent ) {
                if( isset($value->regionId) && !in_array($value->regionId, $listeRegionsIds) ) {
                    array_push($listeRegionsIds, $value->regionId);
                } else {
                    unset($resulatsToView["regionsUtil"]);
                }
            } 

            /* reconstruction du filtre Activites */            
            if( !$isFiltreActivitesPresent ) {
                if( isset($value->activiteId) && !in_array($value->activiteId, $listeActivitesIds) ) {
                    array_push($listeActivitesIds, $value->activiteId);
                } else {
                    unset($resulatsToView["activitesUtil"]);
                }
            } 
        }

        /* Construction des résulats à retourner à la vue */
        if(count($listeRegionsIds) > 0 /*&& array_key_exists('paysId', $values)*/) {
            $regionsUtil = $this->regionsTable->initFiltresRegions( $listeRegionsIds );

            if( $regionsUtil !== null )
                $resulatsToView["regionsUtil"] = $regionsUtil;
        }

        if(count($listePaysIds) > 0 ) {
            $paysUtil = $this->paysTable->initFiltresPays( $listePaysIds );
            if( $paysUtil !== null )
                $resulatsToView["paysUtil"] = $paysUtil;
        }

        if(count($listeActivitesIds) > 0 ) {
            $activitesUtil = $this->activitesSejourTable->initFiltresActivites( $listeActivitesIds );
            if( $activitesUtil !== null )
                $resulatsToView["activitesUtil"] = $activitesUtil;
        }

        return $resulatsToView;
    }

    // public function filtrerSejoursAncien ($filtres)
    // {
    //     $where = new Where();

    //     if ( !empty($filtres) ) {

    //         // filtre activite
    //         if($filtres['activite'] != "") {
    //             $where->equalTo('Sejour.activiteId', $filtres['activite']);
    //         }// filtre activite

    //         // filtre destination
    //         if($filtres['destinations'] != "") {

    //             $aDestinations = explode("-", $filtres['destinations']);

    //             if( !empty($aDestinations) ) {
    //                 if(count($aDestinations) > 0 ) {
    //                     $where->equalTo('Sejour.paysId', $aDestinations[0]);
    //                 }

    //                 if(count($aDestinations) > 1 ) {
    //                     $where->equalTo('Sejour.regionId', $aDestinations[1]);
    //                 }
    //             }
    //         }// fin filtre destinations

    //         // filtre date de départ : table sejour_date (liste des disponibilités)
    //         if($filtres['dateDepart'] != "") {
                
    //             $sub = $this->tableGateway->getSql()->select();

    //             $sub->columns(array(new \Zend\Db\Sql\Expression('Sejour.id')))
    //                 ->where(array('Sejour_date.dateDebut' => date($filtres['dateDepart']) ))
    //                 ->group('Sejour.Id');

    //             $where->In('Sejour.Id', $sub );
    //         }
    //     }
    //     return $where;
    // }

    /* FICHE DETAILS : Récupère les filtres courant et retourne en clair le libellé des filtres sélectionnés */
    public function retourne_filtres_en_clair_fiche ( $filtreValues ) {
        $resulatsToView = array();

        $contenuFiltrePaysPresent = $this->getFiltreFromArray ($filtreValues, 'paysId');
        $contenuFiltreRegionsPresent = $this->getFiltreFromArray ($filtreValues, 'regionId');
        $contenuFiltreActivitesPresent = $this->getFiltreFromArray ($filtreValues, 'activiteId');
        $contenuFiltreAgencePresent = $this->getFiltreFromArray ($filtreValues, 'agenceId');

        if( $contenuFiltrePaysPresent != null && count($contenuFiltrePaysPresent) > 0 ) {
            $listePays = $this->paysTable->initFiltresPays( $contenuFiltrePaysPresent );
            
            array_push($resulatsToView, $listePays);
        }
        if( $contenuFiltreRegionsPresent != null && count($contenuFiltreRegionsPresent) > 0 ) {
            $listeRegions = $this->regionsTable->initFiltresRegions( $contenuFiltreRegionsPresent );

            array_push($resulatsToView, $listeRegions);
        }
        if( $contenuFiltreActivitesPresent != null && count($contenuFiltreActivitesPresent) > 0 ) {
            $listeActivites = $this->activitesSejourTable->initFiltresActivites( $contenuFiltreActivitesPresent );

            array_push($resulatsToView, $listeActivites);
        }
        if( $contenuFiltreAgencePresent != null && count($contenuFiltreAgencePresent) > 0 ) {
            $listeAgence = $this->agenceTable->initFiltresAgence( $contenuFiltreAgencePresent );

            array_push($resulatsToView, $listeAgence);
        }

        return $resulatsToView;
    }

    public function concatener_filtres_en_clair_pour_fiche_detail ( $filtreValues ) {
        $filtres_en_clair = $this->retourne_filtres_en_clair_fiche ( $filtreValues );
        $resulatsToView = array();

        foreach ($filtres_en_clair as $key => $value) {
            if( get_class( $value[0] ) === "Application\Model\Pays" ) {
                
                $valeursConcatenees = $this->concatLibelleFiltres ( $value, 'libellePays' );

                array_push($resulatsToView, $valeursConcatenees);

            } else if( get_class( $value[0] ) === "Application\Model\Regions" ) {

                $valeursConcatenees = $this->concatLibelleFiltres ( $value, 'libelleRegions' );

                array_push($resulatsToView, $valeursConcatenees);
            } else if( get_class( $value[0] ) === "Application\Model\ActivitesSejour" ) {

                $valeursConcatenees = $this->concatLibelleFiltres ( $value, 'libelleAS' );

                array_push($resulatsToView, $valeursConcatenees);
            }
        }

        return $resulatsToView;
    }


    /* fonction de traitement des filtres lors des mises à jour */
    /* mise en cache des résultats si le traitement se fait sur la page d'accueil */
    public function miseAJourDesFiltres ( $filtreValues, $cache) {
        
        $user_session = new Container('filtresession');

        if($filtreValues != null) {

            /* on filtre les séjours en fonction des filtres */
                $result = $this->resultatRecherche($filtreValues);

                // print_r($result);die;

                if( count($result) == 0 ) {
                    return $this->initialiser_les_filtres_page_accueil ();
                }

            /* en fonction des résulats on raffraichit les filtres*/
                $filtresMisAJour = $this->reCreationFiltres( $result, $filtreValues );

            /* mise en session des filtres mis à jour*/
                if($cache){
                    $user_session->filtresCourant = $filtreValues;
                }
                
            /* mise en session des filtres mis à jour*/
                if($cache){
                    $ancienFiltresSession = $user_session->filtresAJour;

                    foreach ($filtresMisAJour as $key => $value) {
                        if( count( $value ) == 0 && count( $ancienFiltresSession[ $key ] ) > 0 ) {
                            $filtresMisAJour[ $key ] = $ancienFiltresSession[ $key ];
                        } else if ( count( $value ) == 0 && count( $ancienFiltresSession[ $key ] ) == 0 ) {
                            if( $key == "paysUtil" ) {
                                /* filtres d'origines pour les pays, filtré sur les séjours en base */
                                $filtresMisAJour[ $key ] = $this->paysTable->fetchAllUsed();
                            } else if ( $key == "regionsUtil" ) {
                                /* filtres d'origines pour les régions, filtré sur les séjours en base */
                                $filtresMisAJour[ $key ] = $this->regionsTable->fetchAllUsed();
                            } else if ($key == "activitesUtil") {
                                $filtresMisAJour[ $key ] = $this->activitesSejourTable->fetchAllUsed();
                            }
                        }
                    }
                    
                    $filtresAJourSession = $filtresMisAJour;
                    unset($filtresAJourSession["resultSet"]);
                    $user_session->filtresAJour = $filtresAJourSession;

                    $filtresMisAJour[ 'filtresSelection' ] = $this->reconstruire_filtres_selectionnes_recherche_accueil ( $filtreValues );
                }

            return $filtresMisAJour;
        }

        return null;
    }

    /* retour d'une page détail d'un séjour sur la page d'accueil */
    public function reconstruire_filtres_selectionnes_recherche_accueil ( $filtreValues ) {

        $resulatsToView = array();
        $filtres_selection_en_clair = $this->retourne_filtres_en_clair_fiche ( $filtreValues );

        foreach ( $filtres_selection_en_clair as $key => $filtres_par_categorie ) {
            foreach ($filtres_par_categorie as $key2 => $datas) {
                $type_objet = get_class( $datas );

                switch ($type_objet) {
                    case 'Application\Model\Pays':
                            $obj = new Pays();
                            $obj->exchangeArray( (array) $datas);

                            $propriete = "paysId";
                            $value = $obj->idPays;
                            $label = $obj->libellePays;
                        break;

                        case 'Application\Model\Regions':
                            $obj = new Regions();
                            $obj->exchangeArray( (array) $datas);

                            $propriete = "regionId";
                            $value = $obj->idRegions;
                            $label = $obj->libelleRegions;
                        break;

                        case 'Application\Model\ActivitesSejour':
                            $obj = new ActivitesSejour();
                            $obj->exchangeArray( (array) $datas);

                            $propriete = "activiteId";
                            $value = $obj->idAS;
                            $label = $obj->libelleAS;
                        break;

                        case 'Application\Model\Agence':
                            $obj = new Agence();
                            $obj->exchangeArray( (array) $datas);

                            $propriete = "agenceId";
                            $value = $obj->id;
                            $label = $obj->libelle;
                        break;
                }

                array_push($resulatsToView, array('label' => $label, 'propriete' => $propriete, 'value' => $value) );
            }
        }

        return $resulatsToView;
    }


    /******************************************************************************************/

    public function getFiltresUtilProprites () {
        return $this->_listeFiltresUtilProprietes;
    }

    public function isFiltre ($filtreValues, $nomFiltre) {
        foreach ($filtreValues as $key => $value) {
            if( array_key_exists( $nomFiltre, $value) ) {
                return true;
            }
        }
        return false;
    }

    /* retourne le contenu d'un filtre parmis ceux définis */
    public function getFiltreFromArray ($filtreValues, $nomFiltre) {
        foreach ($filtreValues as $key => $value) {
            if( array_key_exists( $nomFiltre, $value) ) {
                
                return $value[$nomFiltre];
            }
        }
        return null;
    }

    public function concatLibelleFiltres ( $aFiltres, $propriete ) {
        $concatVale = "";
        foreach ($aFiltres as $key => $value) {
            if( array_key_exists( $propriete, $value) ) {
                if( $concatVale != "" ) {
                    $concatVale .= '; ' . $value->$propriete;
                } else {
                    $concatVale = $value->$propriete;
                }
            }

        }
        return $concatVale;
    }

    public function rechercheSejourParUrl (  $parametre )
    {
        return $this->stringService->ReecritureParametresUrl ( $parametre );
    }

}